package com.bt.dmdb.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.joda.time.LocalDateTime;
import org.springframework.stereotype.Repository;

import com.bt.dmdb.dao.LoginUsersDao;
import com.bt.dmdb.model.BusinessNature;
import com.bt.dmdb.model.Contact;
import com.bt.dmdb.model.CustomerCopy;
import com.bt.dmdb.model.CustomerDetails;
import com.bt.dmdb.model.CustomerDocument;
import com.bt.dmdb.model.CustomerQuestion;
import com.bt.dmdb.model.Document;
import com.bt.dmdb.model.DocumentDto;
import com.bt.dmdb.model.EagPassiveIncome;
import com.bt.dmdb.model.Locations;
import com.bt.dmdb.model.LoginUser;
import com.bt.dmdb.model.Market;
import com.bt.dmdb.model.MemberStatus;
import com.bt.dmdb.model.Question;
import com.bt.dmdb.model.Regulators;
import com.bt.dmdb.model.RestrictedDistributor;
import com.bt.dmdb.model.Role;
import com.bt.dmdb.model.SourceIncome;
import com.bt.dmdb.model.StocksDistribution;

@Repository("usersDao")
public class LoginUsersDaoImpl extends GenericDaoImpl<LoginUser, Long> implements LoginUsersDao {
    
     private List<String> documentNames = new ArrayList<String>();

    public LoginUsersDaoImpl() {
        super(LoginUser.class);
    }

    public LoginUser validateUser(String userName, String password) {
        LoginUser loginUser = (LoginUser) cs().createCriteria(LoginUser.class).add(Restrictions.eq("firstname", userName))
                .add(Restrictions.eq("password", password)).uniqueResult();
        return loginUser;
    }
    
    
    @Override
    public List<CustomerQuestion> getResponseNFFE(long id) {
    	List<CustomerQuestion> customerQuestions = (List<CustomerQuestion>) cs().createCriteria(CustomerQuestion.class).createAlias("question", "q")
    			.add(Restrictions.and(Restrictions.eq("customer.id", id), Restrictions.eq("q.category", "NFFE_Common")))
    			.list();
    	return customerQuestions;
    }
    
    @Override
    public List<CustomerQuestion> getResponseSpecNFFE(long id) {
    	List<CustomerQuestion> customerQuestions = (List<CustomerQuestion>) cs().createCriteria(CustomerQuestion.class).createAlias("question", "q")
    			.add(Restrictions.and(Restrictions.eq("customer.id", id), Restrictions.ne("q.category", "MakerInitial")
    					,Restrictions.ne("q.category", "NFFE_Common")))
    			.list();
    	return customerQuestions;
    }
  
    
    @Override
    public List<CustomerQuestion> getResponseFFI(long id) {
    	List<CustomerQuestion> customerQuestions = (List<CustomerQuestion>) cs().createCriteria(CustomerQuestion.class).createAlias("question", "q")
    			.add(Restrictions.and(Restrictions.eq("customer.id", id), Restrictions.eq("q.category", "FFI_Common")))
    			.list();
    	return customerQuestions;
    }

    @Override
    public List<CustomerQuestion> getResponseSpecFFI(long id) {    	
    	List<CustomerQuestion> customerQuestions = (List<CustomerQuestion>) cs().createCriteria(CustomerQuestion.class).createAlias("question", "q")
    			.add(Restrictions.and(Restrictions.eq("customer.id", id), Restrictions.ne("q.category", "MakerInitial") 
    					, Restrictions.ne("q.category", "FFI_Common")))
    			.list();
    	return customerQuestions;
    }

    public LoginUser getUser(String login) {
    	List<LoginUser> loginUserList= (List<LoginUser>)cs().createCriteria(LoginUser.class).add(Restrictions.eq("firstname", login)).setFetchMode("role", FetchMode.JOIN).list();
    	if (loginUserList.size() > 0)
			return loginUserList.get(0);
		else
			return null;	
	}

    @Override
    public LoginUser getLoggedInUser(Long userId) {
        Criteria criteria = cs().createCriteria(LoginUser.class).add(Restrictions.eq("id", userId));
        return (LoginUser) criteria.list().get(0);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<LoginUser> findAllUsers() {
        return (List<LoginUser>) cs().createCriteria(LoginUser.class).setFetchMode("role", FetchMode.JOIN).list();
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public List<LoginUser> findAllCheckers() {
        return (List<LoginUser>) cs().createCriteria(LoginUser.class).createAlias("role", "r").add(Restrictions.eq("r.name", "Checker")).list();
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public List<Question> findQuesByCategory(String category) {
        return (List<Question>) cs().createCriteria(Question.class).add(Restrictions.eq("category", category)).list();
    }

    @Override
    public void addUser(String firstName, String lastName, String emailId, String password, String role) {
        Role roleObj = (Role) cs().createCriteria(Role.class).add(Restrictions.eq("name", role)).uniqueResult();
        LoginUser loginUser = new LoginUser();
        loginUser.setFirstname(firstName);
        loginUser.setLastname(lastName);
        loginUser.setEmailid(emailId);
        loginUser.setPassword(password);
        loginUser.setRole(roleObj);
        cs().save(loginUser);
    }

    @Override
    public void editUser(Long id, String firstName, String lastName, String emailId, String password, String role) {
        LoginUser loginUser = (LoginUser) cs().createCriteria(LoginUser.class).add(Restrictions.eq("id", id)).uniqueResult();
        Role roleObj = (Role) cs().createCriteria(Role.class).add(Restrictions.eq("name", role)).uniqueResult();
        loginUser.setFirstname(firstName);
        loginUser.setLastname(lastName);
        loginUser.setEmailid(emailId);
        loginUser.setPassword(password);
        loginUser.setRole(roleObj);
        cs().saveOrUpdate(loginUser);
    }

    @Override
    public LoginUser findUserById(long id) {
        return (LoginUser) cs().createCriteria(LoginUser.class).add(Restrictions.eq("id", id)).setFetchMode("role", FetchMode.JOIN).uniqueResult();
    }

    @SuppressWarnings("unused")
	@Override
    public CustomerDetails addCustomerDetails(CustomerDetails details, LoginUser loginUser) {
    	
    	if(details.getId()!=null){
	        CustomerDetails customer = (CustomerDetails) cs().createCriteria(CustomerDetails.class).add(Restrictions.eq("id", details.getId())).uniqueResult();
	        customer.setNameOfEntityCustomer(details.getNameOfEntityCustomer());
	        customer.setTin(details.getTin());
	        customer.setCountryOfIssuance(details.getCountryOfIssuance());
	        customer.setCountryOfIncorporation(details.getCountryOfIncorporation());
	        customer.setLei(details.getLei());
	        customer.setAggregateBalanceExpected(details.getAggregateBalanceExpected());
	        customer.setInvestmentIncomeAsRatioOfGrossIncome(details.getInvestmentIncomeAsRatioOfGrossIncome());
	        customer.setAssetsQuarterlyInvestmentIncome(details.getAssetsQuarterlyInvestmentIncome());
	        customer.setIncorporationDate(details.getIncorporationDate());
	        customer.setBankruptcyFilingDate(details.getBankruptcyFilingDate());
	        customer.setUsOwnersShareDistribution(details.getUsOwnersShareDistribution());
	        customer.setUsOwnersShareValueInDollars(details.getUsOwnersShareValueInDollars());
	        customer.setElectronicAccountNumber(details.getElectronicAccountNumber());
	        customer.setPassiveIncomeofEAG(details.getPassiveIncomeofEAG());
	        customer.setGrossIncomeofEAG(details.getGrossIncomeofEAG());
	        customer.setTotalAssestsEntity(details.getTotalAssestsEntity());
	        customer.setTotalAssestsEag(details.getTotalAssestsEag());
	        customer.setChapter4status(details.getChapter4status());
	        
	        
	        CustomerCopy customermodification =new CustomerCopy();
	        customermodification.setNameOfEntityCustomer(details.getNameOfEntityCustomer());
	        customermodification.setTin(details.getTin());
	        customermodification.setCountryOfIssuance(details.getCountryOfIssuance());
	        customermodification.setCountryOfIncorporation(details.getCountryOfIncorporation());
	        customermodification.setLei(details.getLei());
	        customermodification.setAggregateBalanceExpected(details.getAggregateBalanceExpected());
	        customermodification.setInvestmentIncomeAsRatioOfGrossIncome(details.getInvestmentIncomeAsRatioOfGrossIncome());
	        customermodification.setAssetsQuarterlyInvestmentIncome(details.getAssetsQuarterlyInvestmentIncome());
	        customermodification.setIncorporationDate(details.getIncorporationDate());
	        customermodification.setBankruptcyFilingDate(details.getBankruptcyFilingDate());
	        customermodification.setUsOwnersShareDistribution(details.getUsOwnersShareDistribution());
	        customermodification.setUsOwnersShareValueInDollars(details.getUsOwnersShareValueInDollars());
	        customermodification.setElectronicAccountNumber(details.getElectronicAccountNumber());
	        customermodification.setPassiveIncomeofEAG(details.getPassiveIncomeofEAG());
	        customermodification.setGrossIncomeofEAG(details.getGrossIncomeofEAG());
	        customermodification.setTotalAssestsEntity(details.getTotalAssestsEntity());
	        customermodification.setTotalAssestsEag(details.getTotalAssestsEag());
	        customermodification.setChapter4status(details.getChapter4status());
	        
	        
	        
	        
	        if(customer != null){
	        	 StringBuffer auditLog = new StringBuffer(customer.getAuditLog());
	        	 if(!customer.getAuditLog().contains(MAKER_DATA_COLLECTION_REINITIATED_PENDING))
	             auditLog.append(":"+MAKER_DATA_COLLECTION_REINITIATED_PENDING);
	             customer.setAuditLog(auditLog.toString());
	             customer.setStatus(MAKER_DATA_COLLECTION_REINITIATED_PENDING);
	             
	             customer.setUpdatedBy(loginUser);
	 			 customer.setModificationDate(LocalDateTime.now());
	             
	        	 cs().update(customer);
	        }
	        	
	        else{
	        	
	        	customermodification.setStatus(MAKER_DATA_COLLECTION_PENDING);
	        	customermodification.setAuditLog(MAKER_DATA_COLLECTION_PENDING);
	        	customermodification.setCreatedBy(loginUser);
	        	customermodification.setCreationDate(LocalDateTime.now());
	        	cs().save(customermodification);
	        
	        	
	        	details.setStatus(MAKER_DATA_COLLECTION_PENDING);
	        	details.setAuditLog(MAKER_DATA_COLLECTION_PENDING);
	        	details.setCreatedBy(loginUser);
	        	details.setCreationDate(LocalDateTime.now());
	        	
	        	cs().save(details);
	        }
        
    	}else{
    		   CustomerCopy customermodification =new CustomerCopy();
   	        customermodification.setNameOfEntityCustomer(details.getNameOfEntityCustomer());
   	        customermodification.setTin(details.getTin());
   	        customermodification.setCountryOfIssuance(details.getCountryOfIssuance());
   	        customermodification.setCountryOfIncorporation(details.getCountryOfIncorporation());
   	        customermodification.setLei(details.getLei());
   	        customermodification.setAggregateBalanceExpected(details.getAggregateBalanceExpected());
   	        customermodification.setInvestmentIncomeAsRatioOfGrossIncome(details.getInvestmentIncomeAsRatioOfGrossIncome());
   	        customermodification.setAssetsQuarterlyInvestmentIncome(details.getAssetsQuarterlyInvestmentIncome());
   	        customermodification.setIncorporationDate(details.getIncorporationDate());
   	        customermodification.setBankruptcyFilingDate(details.getBankruptcyFilingDate());
   	        customermodification.setUsOwnersShareDistribution(details.getUsOwnersShareDistribution());
   	        customermodification.setUsOwnersShareValueInDollars(details.getUsOwnersShareValueInDollars());
   	        customermodification.setElectronicAccountNumber(details.getElectronicAccountNumber());
   	        customermodification.setPassiveIncomeofEAG(details.getPassiveIncomeofEAG());
   	        customermodification.setGrossIncomeofEAG(details.getGrossIncomeofEAG());
   	        customermodification.setTotalAssestsEntity(details.getTotalAssestsEntity());
   	        customermodification.setTotalAssestsEag(details.getTotalAssestsEag());
   	        customermodification.setChapter4status(details.getChapter4status());
   	        customermodification.setStatus(MAKER_DATA_COLLECTION_PENDING);
   	        customermodification.setAuditLog(MAKER_DATA_COLLECTION_PENDING);
   	        customermodification.setCreatedBy(loginUser);
   	        customermodification.setCreationDate(LocalDateTime.now());
     	cs().save(customermodification);
    		
    		details.setCreatedBy(loginUser);
    		details.setCreationDate(LocalDateTime.now());
    		details.setStatus(MAKER_DATA_COLLECTION_PENDING);
    		details.setAuditLog(MAKER_DATA_COLLECTION_PENDING);    		
    		    		
    		cs().save(details);
    		
    	}
        return details;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<CustomerDetails> findAllCustomers() {
        /*return (List<CustomerDetails>) cs().createCriteria(CustomerDetails.class)
        		.add(Restrictions.or(Restrictions.and(Restrictions.ne("status", CHECKER_REVIEW_PENDING)
        				, Restrictions.ne("status", "Checker Approved- Resolved")
        				, Restrictions.ne("status", "Checker Rejected- Resolved")
        				, Restrictions.ne("status", "Maker - data collection reinitated - pending"))
        				, Restrictions.isNull("status"))).list();*/
    	return (List<CustomerDetails>) cs().createCriteria(CustomerDetails.class)
        		.add(Restrictions.or(Restrictions.eq("status", MAKER_DATA_COLLECTION_PENDING)
        				, Restrictions.eq("status", MAKER_DUE_DILIGENCE_QUESTIONNAIRE_PENDING)
        				, Restrictions.eq("status", MAKER_DATA_COLLECTION_REINITIATED_PENDING)
        				, Restrictions.isNull("status"))).list();
    }
    
    
    @SuppressWarnings("unchecked")
    @Override
    public List<CustomerDetails> getAllCustomers() {
        /*return (List<CustomerDetails>) cs().createCriteria(CustomerDetails.class)
        		.add(Restrictions.or(Restrictions.and(Restrictions.ne("status", CHECKER_REVIEW_PENDING)
        				, Restrictions.ne("status", "Checker Approved- Resolved")
        				, Restrictions.ne("status", "Checker Rejected- Resolved")
        				, Restrictions.ne("status", "Maker - data collection reinitated - pending"))
        				, Restrictions.isNull("status"))).list();*/
    	return (List<CustomerDetails>) cs().createCriteria(CustomerDetails.class).list();
    }

    
    @SuppressWarnings("unchecked")
    @Override
    public List<CustomerDetails> findAllCustomersChecker() {
        return (List<CustomerDetails>) cs().createCriteria(CustomerDetails.class)
        		.add(Restrictions.or(
        				Restrictions.eq("status", CHECKER_REVIEW_PENDING)
        		      , Restrictions.eq("status", CHECKER_APPROVED_RESOLVED)
        		      , Restrictions.eq("status", CHECKER_REJECTED_RESOLVED)
        		      )).list();
        		//.add(Restrictions.or(Restrictions.ne("status", "Checker Pending"), Restrictions.isNull("status"))).list();
    }
    
    @Override
    public CustomerDetails findCustomerById(long id) {
        return (CustomerDetails) cs().createCriteria(CustomerDetails.class).add(Restrictions.eq("id", id)).uniqueResult();
    }
    
    public Question findQuestionById(long id) {
        return (Question) cs().createCriteria(Question.class).add(Restrictions.eq("id", id)).uniqueResult();
    }

    
     @Override
    public void saveDocs(Long custID, Long docId, String fileName,LocalDateTime localDateTime,String filePath) {
        CustomerDocument document = new CustomerDocument();
        CustomerDetails customer = (CustomerDetails) cs().createCriteria(CustomerDetails.class).add(Restrictions.eq("id", custID)).uniqueResult();
        Document doc = (Document) cs().createCriteria(Document.class).add(Restrictions.eq("id", docId)).uniqueResult();

        document.setFileName(fileName);
        document.setUploadedDate(localDateTime);
        document.setDoc(doc);
        document.setCustomer(customer);
        document.setFilePath(filePath);
        if(filePath!=null){
            document.setStatus(1);
            }
        cs().save(document);
    }
     // code for fetch data from Db like  document name, status and rule for categary n(specific)
    @SuppressWarnings("unchecked")
    @Override
    public List<Document> getDocuments() {
    	List<Document> adminDocList=new ArrayList<Document>();
      	// String selectAdminDocHql = "select d from Document d where d.category='y' and d.rules is not null and d.rules <> '' ";
      	String selectAdminDocHql = "select REPLACE(d.name, '_', ' ') as name, d.id,d.category,d.rules from document d where d.category='n'";    
     	SQLQuery query =cs().createSQLQuery(selectAdminDocHql);
      	query.addEntity(Document.class);  
  		adminDocList = query.list();
  		return adminDocList;
    	
    }   
    // code for fetch data from Db like  document name, status and rule for category y(specific)
    @Override
    public List<Document> getDocuments1() {
    	List<Document> adminDocList=new ArrayList<Document>();
      	// String selectAdminDocHql = "select d from Document d where d.category='y' and d.rules is not null and d.rules <> '' ";
      	String selectAdminDocHql = "select REPLACE(d.name, '_', ' ') as name, d.id,d.category,d.rules from document d where d.category='y'";    
     	//String selectAdminDocHql = "select REPLACE(d.name, '_', ' ') from Document d where d.category in('y')";    
      	SQLQuery query =cs().createSQLQuery(selectAdminDocHql);
      	query.addEntity(Document.class);  
  		adminDocList = query.list();
  		return adminDocList;
    	
    }
    
    @Override
    public List<CustomerDocument> findDocumentByCustId(long id) {
    	List<CustomerDocument> listCustomerDocument = (List<CustomerDocument>) cs()
    													.createCriteria(CustomerDocument.class).add(Restrictions.eq("customer.id", id))
    													.setFetchMode("customer", FetchMode.JOIN).setFetchMode("doc", FetchMode.JOIN)
    													.list();
        return listCustomerDocument;
    }
    
    @Override
    public List<Question> findNFFECommonQuestion() {
    	List<Question> listQuestion = (List<Question>) cs().createCriteria(Question.class).add(Restrictions.eq("category", "NFFE_Common")).list();
        return listQuestion;
        		
    }
    
    @Override
    public Map<Object, Object> findMakerInitialQuestion() {
    	Map<Object, Object> objMap = new HashMap<Object, Object>();
    	List<Question> listQuestion = (List<Question>) cs().createCriteria(Question.class).add(Restrictions.eq("category", "MakerInitial")).list();
    	List<Object> listCat = (List<Object>) cs().createCriteria(Question.class)
    					.add( Restrictions.not( Restrictions.in("category",  new String[] {"NFFE_Common","FFI_Common","MakerInitial"})))
    					.setProjection(Projections.projectionList()
    					.add(Projections.property("id"))
    					.add(Projections.groupProperty("category"))).list();
    			//Projections.distinct(Projections.property("category")));
    	objMap.put("listQuestion", listQuestion);
    	objMap.put("listCategoryQuestion", listCat);
        return objMap;
        		
    }
    
    @Override
    public Object[] saveMakerInitialQuest(String custID, String catL, String quesId0, String ansId0, String quesId1, String ansId1, String catdd) {
    	Object[] catclass = null;
       CustomerDetails customerDetails = findCustomerById(new Long(custID));
       customerDetails.setStatus(MAKER_DUE_DILIGENCE_QUESTIONNAIRE_PENDING);
       StringBuffer auditLog = new StringBuffer(customerDetails.getAuditLog());
       if(!customerDetails.getAuditLog().contains(MAKER_DUE_DILIGENCE_QUESTIONNAIRE_PENDING))
       auditLog.append(":"+MAKER_DUE_DILIGENCE_QUESTIONNAIRE_PENDING);
       customerDetails.setAuditLog(auditLog.toString());
       if(catdd!=null) {
    	   catclass = getCatClassByQId(new Long(catdd));
    	   customerDetails.setChapter4status(catdd+"_"+catclass[1].toString());
       }
       else catclass = getCatClassByQId(new Long(catL));
       
       cs().update(customerDetails);
       Question question0 = findQuestionById(new Long(quesId0));
       Question question1 = findQuestionById(new Long(quesId1));
       char ans0='\u0000';
       if(ansId0.equals("Yes"))ans0='Y';
       if(ansId0.equals("No"))ans0='N';
       if(ansId0.equals("Don't Know"))ans0='D';
       
       char ans1='\u0000';
       if(ansId1.equals("Yes"))ans1='Y';
       if(ansId1.equals("No"))ans1='N';
       if(ansId1.equals("Don't Know"))ans1='D';
    	   
       
       StringBuilder comment = new StringBuilder("");
       saveResponse(customerDetails, question0, ans0, comment.toString());
       
       /*if(ansId1.equals("No")){
    	   if(expiration != null) comment.append("expiration : "+expiration+", "); 
    	   else comment.append("expiration : , "); 
    	   if(circumchange != null) comment.append("circumchange : "+circumchange+", circumstances : "+circumstances+", ");
    	   else comment.append("circumchange : , "); 
    	   if(other != null) comment.append("other : "+other+", othertext : "+othertext+", ");
    	   else comment.append("other : , "); 
    	   saveResponse(customerDetails, question1, ans1, comment.toString());
       }else */
       saveResponse(customerDetails, question1, ans1, comment.toString());
       
       return catclass;
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public Object[] getCatClassByQId(Long id) {
        return (Object[])cs().createCriteria(Question.class).add(Restrictions.eq("id", id)).setProjection(Projections.projectionList().add(Projections.property("classification")).add(Projections.groupProperty("category"))).uniqueResult();
        //Projections.projectionList().add(Projections.property("classification")).add(Projections.groupProperty("category"))			
					//.add(Projections.property("classification"))
					//.add(Projections.groupProperty("category"))).list();
    }
   
    public void saveResponse(CustomerDetails customerDetails, Question question, char answer, String comment) {
    	CustomerQuestion customerQuestion = (CustomerQuestion) cs().createCriteria(CustomerQuestion.class)
    			.add(Restrictions.and(Restrictions.eq("customer.id", customerDetails.getId()), Restrictions.eq("question.id", question.getId())))
    			.uniqueResult();
    	if(customerQuestion != null){
    		customerQuestion.setCustomer(customerDetails);
        	customerQuestion.setQuestion(question);
        	customerQuestion.setAnswer(answer);
        	customerQuestion.setComment(comment);        	
            cs().update(customerQuestion);
    	}else{
    		CustomerQuestion customerQues = new CustomerQuestion();
    		customerQues.setCustomer(customerDetails);
    		customerQues.setQuestion(question);
    		customerQues.setAnswer(answer);
    		customerQues.setComment(comment);
        	
            cs().save(customerQues);
    	}
    	
    }
    // code for replace the specific category '_' to ' ' from table document.
    @SuppressWarnings("unchecked")
	@Override
    public List<Document> getDocumentNames() {
    	List<Document> adminDocList=new ArrayList<Document>();
      	// String selectAdminDocHql = "select d from Document d where d.category='y' and d.rules is not null and d.rules <> '' ";
      	String selectAdminDocHql = "select REPLACE(d.name, '_', ' ') as name, d.id,d.category,d.rules from document d where d.category='n'";    
     	SQLQuery query =cs().createSQLQuery(selectAdminDocHql);
      	query.addEntity(Document.class);  
  		adminDocList = query.list();  		
  		return adminDocList;
    }
    
     public List<String> getDocNameList(String query) {
        String docNames = null;
        query = query.toLowerCase();
        List<String> matched = new ArrayList<String>();
        for(int i=0; i < documentNames.size(); i++) {
            docNames = documentNames.get(i).toLowerCase();
            if(docNames.startsWith(query)) {
                matched.add(documentNames.get(i));
            }
        }
        return matched;
    }
     
 	@Override
 	@SuppressWarnings("unchecked")
 	public List<Object> getListOfNFFECategory() {  
		List<Object> listCat = (List<Object>) cs().createCriteria(Question.class)
     			.add(Restrictions.eq("classification", "NFFE"))
     			.add( Restrictions.ne("category", "NFFE_Common"))
     			.setProjection(Projections.projectionList()
     					.add(Projections.property("id"))
     					.add(Projections.groupProperty("category"))).list();
         return listCat;
         		
     }

	@Override
	public List<Object> getListOfFFICategory() {  
    	List<Object> listCat = (List<Object>) cs().createCriteria(Question.class)
    			.add(Restrictions.eq("classification", "FFI"))
    			.add( Restrictions.ne("category", "FFI_Common"))
    			.setProjection(Projections.projectionList()
    					.add(Projections.property("id"))
    					.add(Projections.groupProperty("category"))).list();
        return listCat;
        		
    }
	
	 // code for rule performing AND OR operation for category y 
	@Override
	public Map<Long,DocumentDto> getRules(){
		Map<Long,DocumentDto> map=new HashMap<Long,DocumentDto>();
		List<Document> docList=null;
		List<String> list=null;
		List<Document> documentList=null;
		List<Integer> listStatus=null;
		List<Long> ruleList=null;
		List<Long> ruleListInt=null;
		List<Integer> statusListInt=null;
		StringBuilder str=null;
		List<String> list1=null;
		int[] status = new int[50];
		int[] myIntArray = new int[50];
		String[] s5=new String[10];
		String ruleStr=null;
		List<Integer> resultList=new ArrayList<Integer>();
		
		String getQueryFromDocument = "select d from Document d where d.category='y' and d.rules is not null and d.rules <> '' ";
		Query docidq=cs().createQuery(getQueryFromDocument);
		docList=docidq.list();

		for(Document document: docList){
			docList=new ArrayList<Document>();
			list=new ArrayList<String>();
			documentList=new ArrayList<Document>();
			listStatus=new ArrayList<Integer>();
			ruleList=new ArrayList<Long>();
			ruleListInt=new ArrayList<Long>();
			statusListInt=new ArrayList<Integer>();
			DocumentDto dto=new DocumentDto();
			
			if(document.getRules()!=null){
				String ruleStrFetched=null;
				Query q=cs().createQuery("select d.rules from Document d where d.id=:documentId");
				q.setParameter("documentId", document.getId());
				list=q.list();

				for (String rule : list) {
					if(rule != null){
						ruleStrFetched=rule;
						ruleStr=rule.replaceAll("\\(", "");
				ruleStr=ruleStr.replaceAll("\\)", "");
					str	=new StringBuilder();
						String[] parts = ruleStr.replace(" ", "").split("AND|OR");
						for (int i = 0; i < parts.length; i++) {
							str=str.append(parts[i]+ " ");
						}	
						
						StringTokenizer str1=null;
								str1=new StringTokenizer(str.toString());
								
						list1=new ArrayList<String>();
						while (str1.hasMoreTokens()) {
							list1.add(str1.nextToken());
						}
					}
				}

				for (int i = 0; i < list1.size(); i++) {
					try{
						Query q1=cs().createQuery("select d.id from Document d where d.name=:rule");
						q1.setParameter("rule",list1.get(i));
						ruleList=q1.list();
						for (long  id : ruleList) {
							ruleListInt.add(id);
						}
					}catch(Exception e){
						System.out.println("no document Id was found for the rule : "+list.get(i));
					}
				}
				for (int i = 0; i < ruleListInt.size(); i++) {
					try{
						Query q1=cs().createQuery("select d.status from CustomerDocument d where d.doc.id=:dID");
						q1.setParameter("dID",new Long(ruleListInt.get(i)));
						listStatus=q1.list();
						for (int stat : listStatus) {
							statusListInt.add(stat);
						}
					}catch(Exception ne){
						System.out.println("LoginUserDaoImpl: getRules:- There is no documentId="+ruleList.get(i)+ "in customer table");
					}
				}
				int x=0;
				for (int i = 0; i < statusListInt.size(); i++) {
					status[i]=statusListInt.get(i);
					ruleStrFetched=ruleStrFetched.replaceFirst(String.valueOf(list1.get(i)), String.valueOf(status[i]));
				}
				boolean j=false;
				try {
					ruleStrFetched = ruleStrFetched.replaceAll("AND", "&");
					ruleStrFetched = ruleStrFetched.replaceAll("OR", "|");
					ruleStrFetched = ruleStrFetched.replaceAll("1", "true");
					ruleStrFetched = ruleStrFetched.replaceAll("0", "false");
					ruleStrFetched = ruleStrFetched.replaceAll(" [&] ", "&&");
					ruleStrFetched = ruleStrFetched.replaceAll(" [|] ", "||"); 
					j=Boolean.valueOf(interpret(ruleStrFetched));
				} catch (NumberFormatException e) {
					System.out.println("Error while parsing the string : Number Format exception" +e.getMessage());
				} catch (ScriptException e) {
					System.out.println("Error while parsing the string : Script Exception" +e.getMessage());
				}catch (NullPointerException e) {
					System.out.println("Error while parsing the string : NullPointer Exception" +e.getMessage());
				}if(j){
					x=1;
					//resultList.add(x);
					dto.setId(document.getId());
					dto.setName(document.getName());
					dto.setRules(document.getRules());
					dto.setStatus(x);
					map.put(dto.getId(), dto);
				}else{
					dto.setId(document.getId());
					dto.setName(document.getName());
					dto.setRules(document.getRules());
					dto.setStatus(x);
					map.put(dto.getId(), dto);
				}
			}
		}
		return map;
	}
	
	
	public static String interpret(String js) throws NumberFormatException, ScriptException {
		ScriptEngineManager mgr = new ScriptEngineManager();
		ScriptEngine engine = mgr.getEngineByName("JavaScript");
		return engine.eval(js).toString();
	}

//code for select document 
    @SuppressWarnings("unchecked")
    @Override
    public List<Document> findDocumentRules() {
    	Query q = cs().createQuery("select d.name from Document d where d.category=:docCategory");
        return q.list();
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public List<CustomerDocument> documentUploded(long id) {
  	   	List listCustomerDocument = (List) cs().createCriteria(CustomerDocument.class)
    											.setFetchMode("customer", FetchMode.JOIN).setFetchMode("doc", FetchMode.JOIN)
    											.add(Restrictions.and(Restrictions.eq("customer.id", id),Restrictions.eq("status", 1))).list();
    	return listCustomerDocument;
    }
   
    //code for save the customer document
    @Override
    public void saveDocumentRulesByDocId(DocumentDto y) {
    	try{
    	  String hql = "update Document d set d.rules=:docRules where d.id=:docId";
 	      Query docRulequery = cs().createQuery(hql);
 	      docRulequery.setParameter("docId", y.getId());
 	      docRulequery.setParameter("docRules", y.getRules());
 	      int result = docRulequery.executeUpdate();
        }
    	catch(HibernateException e){
            e.printStackTrace();
            System.out.println("in exception");
        }
    }
    //code for delete the customer document
    @Override
    public void deleteByCustomerId(CustomerDocument y) {
    	try{
    	  String deleteHql = "delete from  CustomerDocument d where d.id=:deleteCustDocId";
 	      Query deleteCustDocQuery = cs().createQuery(deleteHql);
 	      deleteCustDocQuery.setParameter("deleteCustDocId", y.getId()); 	
 	      int result = deleteCustDocQuery.executeUpdate();
        }catch(HibernateException e){
            e.printStackTrace();
            System.out.println("in exception");
        }
    }
    //code for delete the Admin for document
    @Override
    public void deleteAdminByDocumentId(Document y) {
    	try{
    	  String updateAdminHql = "update Document d set d.rules=:docRules where d.id=:docId";
 	      Query updateAdminDocQuery = cs().createQuery(updateAdminHql);
 	      updateAdminDocQuery.setParameter("docId", y.getId());
 	      updateAdminDocQuery.setParameter("docRules", "");
	      int resultUpdate = updateAdminDocQuery.executeUpdate();
	      System.out.println("Rows affected: " + resultUpdate);
        }catch(HibernateException e){
            e.printStackTrace();
            System.out.println("in exception");
        }
    }
    //code for delete the Admin rule for document
    @SuppressWarnings("unchecked")
	@Override
	public List<DocumentDto> getAdminDocRules(){
    	List<DocumentDto> adminDocList=new ArrayList<DocumentDto>();
    	String selectAdminDocHql = "select d from Document d where d.category='y' and d.rules is not null and d.rules <> '' "; 
		Query selectAdminQuery = cs().createQuery(selectAdminDocHql);
		adminDocList = selectAdminQuery.list();
		return adminDocList;
    }

	@Override
	public void deleteUserById(long id) {
		LoginUser loginUser = (LoginUser) cs().createCriteria(LoginUser.class).add(Restrictions.eq("id", id)).uniqueResult();
		if(loginUser != null)
		cs().delete(loginUser);
	}

	@Override
	public void saveAllUsers(List<LoginUser> y) {
		//System.out.println("::: kkj :::");
		for(LoginUser l:y){
			if(l.getId()!=null){
				LoginUser loginUser = (LoginUser) cs().createCriteria(LoginUser.class).add(Restrictions.eq("id", l.getId())).uniqueResult();
				loginUser.setFirstname(l.getFirstname());
				loginUser.setLastname(l.getLastname());
				loginUser.setEmailid(l.getEmailid());
				loginUser.setPassword(l.getPassword());
		
				cs().update(loginUser);
			}
			else{
				//Role role = new Role(new Long(2),"maker");
				//l.setRole(role);
				Role role = (Role) cs().createCriteria(Role.class).add(Restrictions.eq("id", new Long(2))).uniqueResult();
				l.setRole(role);
				cs().save(l);
			}
		}
		
	}

	@Override
	public void saveAllBusinessNature(List<BusinessNature> y) {
		
		for(BusinessNature businessNature:y){
			cs().save(businessNature);
		}
	}

	@Override
	public void saveAllEagMemberStatus(List<MemberStatus> y) {
		
		for(MemberStatus memberStatus:y){
			cs().save(memberStatus);
	
		}
	}

	@Override
	public void saveAllPassiveIncome(List<EagPassiveIncome> y) {
	
		for(EagPassiveIncome eagPassiveIncome:y){
			cs().save(eagPassiveIncome);
	
		}
		
	}

	@Override
	public void saveAllExchangeMarket(List<Market> y) {

		for(Market market:y){
			cs().save(market);
	
		}
		
	}

	@Override
	public void saveAllLocation(List<Locations> y) {
		
		for(Locations locations:y){
			cs().save(locations);
	
		}
		
	}

	@Override
	public void saveAllRegulators(List<Regulators> y) {
	
		for(Regulators regulators:y){
			cs().save(regulators);
	
		}
	}

	@Override
	public void saveAllRestrictedDistributor(List<RestrictedDistributor> y) {
		for(RestrictedDistributor restrictedDistributor:y){
			cs().save(restrictedDistributor);
	
		}
		
	}

	@Override
	public void saveAllStocksDistribution(List<StocksDistribution> y) {
		for(StocksDistribution stocksDistribution:y){
			cs().save(stocksDistribution);
	
		}
		
	}

	@Override
	public void saveAllSourceIncome(List<SourceIncome> y) {
		for(SourceIncome sourceIncome:y){
			cs().save(sourceIncome);
	
		}
	}

	@Override
	public void saveAllContact(List<Contact> y) {
		for(Contact contact:y){
			cs().save(contact);
	
		}	
	}
	//code for get all data for CustomerDetails for checker and maker
	@SuppressWarnings("unchecked")
    @Override
    public List<CustomerDetails> getAllAuditor() {
		System.out.println("::  getAllAuditor :: impl class ::: ");
        List<CustomerDetails> listGetAllCustomerDetails =new ArrayList<CustomerDetails>();
        String getAllCustomerHQL = "select cust from CustomerDetails cust ";
        Query getAllCustomerQuery = cs().createQuery(getAllCustomerHQL);
        listGetAllCustomerDetails = getAllCustomerQuery.list();
        return listGetAllCustomerDetails;
    }
}
